echarts 使用小结

现在开发项目,提到图表,十有八九都会选择 echarts,不论是使用、性能或者社区活跃度都不错。

使用

react 项目可以使用 echarts-for-react^3 版本对应 echarts^5

import ReactECharts from "echarts-for-react";

const option = {};

<ReactECharts
  option={option}
  notMerge={true}
  lazyUpdate={true}
  onChartReady={this.onChartReadyCallback}
  onEvents={EventsDict}
/>;

绝大部分项目都是只需要绘制小数据量的图表,外加一些动画或者悬浮交互,这些通过调用 api 就能满足需求。当然,api 也确实有很多,建议先熟悉初始配置、setOption 、事件,之后再根据具体图表类型再进一步熟悉和应用

文档链接

遇到的问题

实际上我遇到的问题,可以归纳为 高频数据下发,数据量不保证,前端页面需要确保曲线图绘制的实时性。这里涉及到三点可能导致卡顿的问题

  • 高频数据
  • 大对象数据解析
  • 绘制曲线图

解决办法主要是以下几点:

1.数据解析角度

  • 减小数据量

  • 后端(c++)解析数据,相比 js 解析数据肯定要更快

  • web worker。分担主线程解析和生成曲线数据的压力

  • 分流。可在后端或者 worker 中处理,按固定频率绘制曲线

    2.绘制角度

  • 降采样。不适配需求,当然 echarts 有很好的降采样算法,单看趋势的话,其实完全可以试试 ~

  • 去除动画,减少绘制耗时

  • 设置 showSymbol 为 false,即减少绘制元素,包括不必要的悬浮框等

  • 只渲染固定范围,控制耗时

最终的优化方案其实就用到了上面提到的几点:

  • 后端处理数据,转换成前端绘制需要的曲线数据,做好节流(比如 1s 绘制一次)
  • 前端接收 json 并解析
  • 维护一个队列,控制只绘制固定范围(用户自定义)的曲线,将耗时控制在 30ms 以内(不用 worker 是因为这一步处理耗时并不多)
  • 前端去除多余的动画、绘制元素以确保不产生无用的耗时

其他优化思路,待验证

  • 升级 echarts5,使用脏矩形优化,初步对比优化效果不明显。可能是数据量还没达到百万级别?
  • Web Worker + Transferable Objects
  • 增量渲染 appendData
  • 离屏渲染
  • canvas 分层

这些思路可能还要研究源码才能验证,因为经过之前的优化方案已经足以满足需求也就不再继续研究了。有空的话接着学习下 ~

按需引入

默认的引入方式会引入 echarts 中所有的图表和组件,建议按需引入

// 默认引入方式
import * as echarts from "echarts";

按需引入,详情参考 按需引入 ECharts 图表和组件,主要代码如下:

// 引入 echarts 核心模块
import * as echarts from "echarts/core";
import { BarChart } from "echarts/charts";
import { TitleComponent, TooltipComponent } from "echarts/components";
import { LabelLayout } from "echarts/features";
// NOTE: 必须引入渲染器
import { CanvasRenderer } from "echarts/renderers";
// 注册组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  BarChart,
  LabelLayout,
  CanvasRenderer,
]);
// 接下来的使用就跟之前一样了
const myChart = echarts.init(document.getElementById("chart"));
myChart.setOption({
  // ...
});

echarts-for-react 按需引入(对于 echarts5)

import ReactEChartsCore from "echarts-for-react/lib/core";
import * as echarts from "echarts/core";
import { LineChart } from "echarts/charts";
import {
  GridComponent,
  TooltipComponent,
  TitleComponent,
  DatasetComponent,
} from "echarts/components";
// NOTE: 必须引入渲染器
import {
  CanvasRenderer,
  // SVGRenderer,
} from "echarts/renderers";

echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LineChart,
  CanvasRenderer,
]);

const option = {};

<ReactEChartsCore
  echarts={echarts}
  option={option}
  notMerge={true}
  lazyUpdate={true}
  onChartReady={this.onChartReadyCallback}
  onEvents={EventsDict}
/>;

echarts 5 以下版本的按需引入参考文档(搜 With Echarts.js v3 or v4:) https://github.com/hustcc/echarts-for-react/

图表对比

实际上我用过的图表库很少,所以这里只是简单提一嘴..更详细的 benchmark 还需要自行搜索资料和验证 ~

  • echarts。不论是图表类型、api、使用体验和性能都是目前最佳,但是封装程度非常高,所以很难对其进一步抽象和封装,表现为定制化能力差
  • G2。对比前者,在数据对图形的控制上要更灵活,即定制化能力更强
  • biz-charts。基于 G2 进一步封装,更易于使用

在这版需求中,其实我基本上复刻了 webviz 的曲线图组件,支持实时和离线场景,后续可以尝试封装成通用组件,并提供下借鉴经验。可以期待下哈 ~